<template>
	<form @submit="search">
		<view class="flex search-box">
			<view class="flex-1">
				<input class="uni-input" name="keyword" placeholder="请输入球员名称" v-model="keyword" />
			</view>
			<button form-type="submit" size="mini" class="btn">搜索</button>
		</view>
	</form>
	<view class="content">
		<view id="container" style="background: #f9f9f9;"></view>
	</view>
</template>

<script setup>
	import G6 from '@antv/g6'; //https://g6-v4.antv.vision/manual/introduction
	import {
		Graph
	} from '@antv/g6';
	import schedule from './js/schedule.js';


	import {
		ref,
		reactive,
		computed,
		getCurrentInstance,
		watch,
		onMounted
	} from 'vue'
	const {
		proxy,
	} = getCurrentInstance()
	import {
		onReady,
		onLoad,
		onShow,
		onPageScroll,
		onShareAppMessage
	} from '@dcloudio/uni-app'
	const props = defineProps({
		numberkey: {
			type: [String, Number],
			default: '64double', // 32double:32双败
		}
	})
	G6.registerNode(
		'itemNode', {
			options: {
				style: {},
				stateStyles: {
					hover: {},
					selected: {},
				},
			},
			/**
			 * 绘制节点，包含文本
			 * @param  {Object} cfg 节点的配置项
			 * @param  {G.Group} group 图形分组，节点中图形对象的容器
			 * @return {G.Shape} 返回一个绘制的图形作为 keyShape，通过 node.get('keyShape') 可以获取。
			 * 关于 keyShape 可参考文档 核心概念-节点/边/Combo-图形 Shape 与 keyShape
			 */
			draw: (cfg, group) => {
				//最外面的那层
				const shape = group.addShape('rect', {
					draggable: true,
					attrs: {
						x: -50,
						y: -26,
						width: 100,
						height: 52,
						fill: '#ffffff', //填充色
						stroke: '#999999', //边框
						radius: 8,
					},
				});
				//文字
				group.addShape('text', {
					attrs: {
						textBaseline: 'top',
						y: 4 - 26,
						x: 4 - 35,
						lineHeight: 16,
						text: cfg.label,
						fill: '#333',
					},
				});
				group.addShape('text', {
					attrs: {
						textBaseline: 'top',
						y: 20 - 26,
						x: 4 - 50,
						lineHeight: 16,
						text: cfg.name0,
						fill: '#333',
					},
				});
				group.addShape('text', {
					attrs: {
						textBaseline: 'top',
						y: 36 - 26,
						x: 4 - 50,
						lineHeight: 16,
						text: cfg.name1,
						fill: '#333',
					},
				});
				return shape;
			},
			/**
			 * 绘制后的附加操作，默认没有任何操作
			 * @param  {Object} cfg 节点的配置项
			 * @param  {G.Group} group 图形分组，节点中图形对象的容器
			 */
			afterDraw(cfg, group) {
				// console.log('afterDraw');
			},
			/**
			 * 更新节点，包含文本
			 * @override
			 * @param  {Object} cfg 节点的配置项
			 * @param  {Node} node 节点
			 */
			update(cfg, node) {
				const group = node.getContainer(); // 获取容器
				const shapeLabel = group.get('children')[1]; // 按照添加的顺序
				const shapeName0 = group.get('children')[2]; // 按照添加的顺序
				const shapeName1 = group.get('children')[3]; // 按照添加的顺序
				shapeName0.attr({
					text: `${cfg.name0||''}`
				});
				shapeName1.attr({
					text: `${cfg.name1||''}`
				});
				// console.log('update');
				// console.log(node);
				// console.log(cfg);
			},
			/**
			 * 更新节点后的操作，一般同 afterDraw 配合使用
			 * @override
			 * @param  {Object} cfg 节点的配置项
			 * @param  {Node} node 节点
			 */
			afterUpdate(cfg, node) {},
			/**
			 * 响应节点的状态变化。
			 * 在需要使用动画来响应状态变化时需要被复写，其他样式的响应参见下文提及的 [配置状态样式] 文档
			 * @param  {String} name 状态名称
			 * @param  {Object} value 状态值
			 * @param  {Node} node 节点
			 */
			setState(name, value, node) {
				const group = node.getContainer(); // 获取容器
				const shapeRect = group.get('children')[0]; // 按照添加的顺序
				const shapeLabel = group.get('children')[1];
				const shapeName0 = group.get('children')[2];
				const shapeName1 = group.get('children')[3];

				const resetNode = () => {
					shapeRect.attr({
						fill: '#ffffff', //填充色
						stroke: '#999999',
					});
					shapeLabel.attr({
						fill: '#333',
					});
					shapeName0.attr({
						fill: '#333',
					});
					shapeName1.attr({
						fill: '#333',
					});
				}
				// || name == 'selected'
				if (name == 'active') {
					if (value) {
						shapeRect.attr({
							fill: '#B37D02', //填充色
							stroke: '#B37D02', //边框
						});
						shapeLabel.attr({
							fill: '#ffffff',
						});
						shapeName0.attr({
							fill: '#ffffff',
						});
						shapeName1.attr({
							fill: '#ffffff',
						});
					} else {
						resetNode();
					}
				}
			},
			/**
			 * 获取锚点（相关边的连入点）
			 * @param  {Object} cfg 节点的配置项
			 * @return {Array|null} 锚点（相关边的连入点）的数组,如果为 null，则没有控制点
			 */
			// getAnchorPoints(cfg) {},
			getAnchorPoints() {
				return [
					[0, 0.5], // 左侧中间
					[1, 0.5], // 右侧中间
					[0.5, 0], // 顶部中间
					[0.5, 1], // 底部中间
				];
			},
		},
		// 继承内置节点类型的名字，例如基类 'single-node'，或 'circle', 'rect' 等
		// 当不指定该参数则代表不继承任何内置节点类型
		// extendedNodeType,
		'rect'
	);
	const scheduleName = props.numberkey || '32double';
	const rowSpace = scheduleName == '4single'?200:50;
	const colSpace = scheduleName == '4single'?100:50;
	const graphData = new schedule(scheduleName,100,52,rowSpace,colSpace);
	
	
	const graph = ref();
	// 实例化 minimap 插件
	const minimap = new G6.Minimap({
		size: [100, 100],
		className: 'minimap',
		type: 'delegate',
	});
	onMounted(() => {
		let res = uni.getSystemInfoSync()
		graph.value = new Graph({
			// plugins: [minimap], // 将 minimap 实例配置到图上
			container: "container",
			width: res.windowWidth,
			height: res.windowHeight,
			modes: {
				// 支持的 behavior
				default: ['drag-canvas', 'zoom-canvas', 'click-select'],
				// edit: ['click-select'],
			},
			fitCenter: true,
			fitView: true,
			minZoom: 0.09,
			maxZoom: 2,
			defaultNode: {
				type: "itemNode",
				style: {
					fill: "#ffffff",
				},
			},
			defaultEdge: {
				type: 'polyline',
				style: {
					stroke: "#999999"
				}
			}
		});
		graph.value.on('node:touchstart', (e) => {
			// console.log(e)
			uni.showToast({
				title: "场次号：" + e.item._cfg.id
			})
		})
		graph.value.on('node:click', (e) => {
			// console.log(e.item._cfg.id)
			uni.showToast({
				title: "场次号：" + e.item._cfg.id
			})
		})
		graph.value.data(graphData);
		graph.value.render();
	})
	const list = ref([])
	const getData = () => {
		setTimeout(() => {
			let testList = [{
					id: '1',
					name0: '张三',
					name1: '赵大大',
					name0Key: '1',
					name1Key: '2'
				},
				{
					id: '2',
					name0: '王五',
					name1: '赵大大',
					name0Key: '3',
					name1Key: '4'
				},
				{
					id: '4',
					name0: '赵大大',
					name1: '赵地主',
					name0Key: '567',
					name1Key: '123'
				},
			];
			list.value = testList;
			testList.forEach(v => {
				// 通过 ID 查询节点实例
				const item = graph.value.findById(v.id);
				const model = {
					name0: `${v.name0Key}. ${v.name0}`,
					name1: `${v.name1Key}. ${v.name1}`,
				}
				graph.value.updateItem(item, model);
			})
		}, 1000)
	}

	const keyword = ref('');
	const oldKeyword = ref('');
	const searchResult = ref([])
	const search = () => {
		let resultList = [];
		if (searchResult.value.length > 0) {
			// 清空先前搜索的高亮
			searchResult.value.forEach(v => {
				graph.value.setItemState(v.id, 'active', false);
			})
		}
		if (!keyword.value) {
			resultList = []
		} else if (oldKeyword.value == keyword.value) {
			resultList = JSON.parse(JSON.stringify(searchResult.value));
		} else {
			resultList = list.value.filter(v => {
				if (v.name0.includes(keyword.value)) {
					return true
				}
				if (v.name1.includes(keyword.value)) {
					return true
				}
				return false
			})
		}
		oldKeyword.value = keyword.value;
		if (resultList.length == 0) {
			uni.showToast({
				title: '暂无结果',
				icon: 'none'
			})
			searchResult.value = resultList;
			return false;
		}
		resultList.forEach(v => {
			graph.value.setItemState(v.id, 'active', true);
		})
		let _index = resultList.findIndex(v => !v.focusFlag);
		if (_index == -1) {
			resultList.forEach(v => {
				v.focusFlag = false;
			})
			_index = 0;
		}
		const item = graph.value.findById(resultList[_index].id);
		// 动画地移动，并配置动画
		graph.value.focusItem(item, true, {
			easing: 'easeCubic',
			duration: 400,
		});
		// graph.value.zoomTo(0.2);
		resultList[_index].focusFlag = true;

		searchResult.value = resultList;
	}

	onReady(() => {
		console.log('onReady')
	})
	onLoad(async (d) => {
		console.log('onLoad')
		getData();

	})
	onShow(async () => {


	})

	onPageScroll(e => {

	})
</script>


<style>
	.flex {
		display: flex;
	}

	.flex-1 {
		flex: 1;
	}

	.search-box {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		margin: 28upx;
		border: 1px solid #dddddd;
		background-color: #ffffff;
		border-radius: 10upx;
	}

	.search-box .uni-input {
		line-height: 28upx;
		height: 68upx;
		padding: 0 20upx;
		font-size: 24upx;
		overflow: hidden;
	}

	.search-box .btn {
		line-height: 68upx;
		height: 68upx;
		font-size: 24upx;
		background: #B37D02;
		color: #ffffff;

	}

	.search-box .btn::after {
		display: none;
	}
	.minimap {
		position: absolute;
		left: 0;
		bottom: 0;
		background-color: #ffffff;
	}
</style>